﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace nMongo
{
    public static class MongoRepositoryExtensions
    {
        #region Graveyard Control
        public static void AddToGraveyard<T>(this MongoRepository<T> repository, T deadObject)
            where T : class
        {
            repository.MortalCollection.Insert(deadObject);
        }

        internal static void AutoDetectGraveyardAdd<T>(this MongoRepository<T> repository, T deadObject)
            where T : class
        {
            bool hasAttribute = typeof(T).CustomAttributes.Any(x => x.AttributeType == typeof(MongoMortalCollectionAttribute));

            if (hasAttribute)
            {
                repository.AddToGraveyard(deadObject);
            }
        } 
        #endregion

        #region Persistency Control
        internal static void AutoDetectPersistencyByObject<T>(this MongoRepository<T> repository, MongoPersistencyState state, object oneObject)
            where T : class
        {
            Type objectType = typeof(T);
            bool hasAttribute = objectType.CustomAttributes.Any(x => x.AttributeType == typeof(MongoEnablePersistencyControlAttribute));
            bool forceDisable =
                hasAttribute ?
                (bool)(typeof(T).CustomAttributes
                    .SingleOrDefault(x => x.AttributeType == typeof(MongoEnablePersistencyControlAttribute)).NamedArguments
                    .Single(x => x.MemberName == "ForceDisable").TypedValue.Value)
                : false;

            if (!forceDisable
                && (repository.Connection.PersistencyControlEnabled == MongoPersistencyOptions.Enabled
                   || (repository.Connection.PersistencyControlEnabled == MongoPersistencyOptions.Mixed && hasAttribute)))
            {
                MongoPersistencyControlEngine.GetInstance().SetObjectPersistencyByObject(objectType, oneObject, state);
            }
        }

        internal static void AutoDetectPersistencyById<T>(this MongoRepository<T> repository, MongoPersistencyState state, object id)
            where T : class
        {
            Type objectType = typeof(T);
            bool hasAttribute = objectType.CustomAttributes.Any(x => x.AttributeType == typeof(MongoEnablePersistencyControlAttribute));
            bool forceDisable =
                hasAttribute ?
                (bool)(typeof(T).CustomAttributes
                    .SingleOrDefault(x => x.AttributeType == typeof(MongoEnablePersistencyControlAttribute)).NamedArguments
                    .Single(x => x.MemberName == "ForceDisable").TypedValue.Value)
                : false;

            if (!forceDisable
                && (repository.Connection.PersistencyControlEnabled == MongoPersistencyOptions.Enabled
                   || (repository.Connection.PersistencyControlEnabled == MongoPersistencyOptions.Mixed && hasAttribute)))
            {
                MongoPersistencyControlEngine.GetInstance().SetObjectPersistencyById(objectType, id, state);
            }
        }  
        #endregion
    }
}
